(function(){
    Date.prototype.format = function(fmt) {  
        var o = {  
            "M+" : this.getMonth()+1, //月份  
            "d+" : this.getDate(), //日  
            "h+" : this.getHours()%12 == 0 ? 12 : this.getHours()%12, //小时  
            "H+" : this.getHours(), //小时  
            "m+" : this.getMinutes(), //分  
            "s+" : this.getSeconds(), //秒  
            "q+" : Math.floor((this.getMonth()+3)/3), //季度  
            "S" : this.getMilliseconds() //毫秒  
        };
        if(/(y+)/.test(fmt)){  
            fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));  
        }
        for(var k in o){  
            if(new RegExp("("+ k +")").test(fmt)){  
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));  
            }  
        }  
        return fmt;  
    }
    
    var slice = Array.prototype.slice;
    var Popbox = function (element, options) { //element为弹窗wrap
        this.options = options;
        this.$element = $$(element);
        var that = this;
        this.$element.bind('click', function(e){
            var target = e.target;
            if(target && target.getAttribute("data-dismiss") == 'popbox'){
                that.hide();
            }
        });
        if(window.dmInfo) dmInfo.hidePopbox = function(){that.hide();}
        
        this.repos = function(){
            var wHt = document.documentElement.clientHeight || window.innerHeight;//可见窗口高度
            var boxHt = element.offsetHeight;
            var top = (wHt - boxHt) / 2;
            if(top < 0) top = 0;
            else if(top > 80) top -= 25;
            that.$element.css({top:top});
            if(that.options.zIndex){
                that.$element.css({zIndex : that.options.zIndex + 1});
            }
        };
    }

    Popbox.prototype = {
        constructor: Popbox, 
        toggle: function () {
            return this[!this.isShown ? 'show' : 'hide']();
        }, 
        show: function () {
            var that = this;
            this.isShown = true;
            this.escape();
            this.backdrop(function () {
                var parent = that.$element[0].parentNode;
                if (!parent) {
                    document.body.appendChild(that.$element[0]);
                }

                that.$element.show();

                that.$element
                    .addClass('in')
                    .attr('aria-hidden', false);
            });
            this.repos();
            $$(window).bind("resize", this.repos);
        }, 
        hide: function (e) {
            e && e.preventDefault();

            var that = this;
            this.isShown = false;
            this.escape();

            this.$element
                .removeClass('in')
                .attr('aria-hidden', true)

            this.hidePopbox();
            $$(window).unbind("resize", this.repos);
        }, 
        escape: function () {
            var that = this;
            if (this.isShown && this.options.keyboard) {
                this.$element.bind('keyup', function ( e ) {
                    e.which == 27 && that.hide();
                });
            } else if (!this.isShown) {
                this.$element.unbind('keyup');
            }
        },
        hidePopbox: function () {
            var that = this;
            this.$element.hide();
            this.backdrop(function () {
                that.removeBackdrop();
                that.$element.trigger('hidden');
            })
        }, 
        removeBackdrop: function () {
            if(this.$backdrop){
                var backdrop = this.$backdrop[0];
                backdrop.parentNode.removeChild(backdrop);
                this.$backdrop = null;
            }
        }, 
        backdrop: function (callback) {
            var that = this, 
                animate = this.$element.hasClass('fade') ? 'fade' : '';

            if (this.isShown && this.options.backdrop) {
                var doAnimate = animate;

                var div = document.createElement("div");
                div.className = "popbox-backdrop " + animate;
                this.$backdrop = $$(div);
                document.body.appendChild(div);

                this.$backdrop.bind("click",
                    this.options.backdrop == 'static' ?
                                    this.$element[0].focus.bind(this.$element[0])
                                    : this.hide.bind(this)
                )

                if (doAnimate) div.offsetWidth // force reflow

                this.$backdrop.addClass('in');
                if(this.options.zIndex){
                    this.$backdrop.css({zIndex : this.options.zIndex});
                }

                if (!callback) return;

                callback();

            } else if (!this.isShown && this.$backdrop) {
                this.$backdrop.removeClass('in');
                callback();
            } else if (callback) {
                callback();
            }
        }
    };

    $$.fn.isPoped = function(){
        var el = this[0];
        return el.popbox && el.popbox.isShown;
    }
    $$.fn.popbox = function (option) {
        return this.each(function () {
            var data = this['popbox'];
            var options = $$.extend({}, $$.fn.popbox.defaults, typeof option == 'object' && option);
            if (!data) {
                this['popbox'] = data = new Popbox(this, options);
            }
            if (typeof option == 'string'){
                data[option]()
            } else if (options.show){
                data.show()
            }
        })
    }

    $$.fn.popbox.defaults = {
        backdrop: 'static', 
        keyboard: true,
        show: true
    };

    $$.fn.popbox.Constructor = Popbox;
    
    $$(document).bind('click', function (e) {
        var target = e.target;
        if(!target || !target.getAttribute("data-toggle")){
            target = target.parentNode;
        }
        if(!target || target.getAttribute("data-toggle") != 'popbox') return;
        
        var $this = $$(target);
        var href = $this.attr('href');
        var $target = $$($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, '')));
        var option = $target[0]['popbox'] ? 'toggle' : {  };
        e.preventDefault();
        $target.popbox(option);
    });
    
    var $body = $$("body");
    
    //fake confirm
    var $confirm = $$('<div>').addClass("popbox fade").hide();
    $confirm.html('<div class="popbox-body alert-body" id="confirm-body"></div>'
                + '<div class="popbox-footer">'
                + '<a data-dismiss="popbox" href="javascript:">取消</a>'
                + '<input class="btn btn-success btn-big" type="submit" value="确 定" id="confirm-ok" /></div>').appendTo($body);
    $$.confirm = function(cond, msg, callback){
        if(!cond) {
            if($$.isFunction(callback)) callback();
            return;
        }
        $confirm.find("#confirm-body").html(msg.replace(/(\r|\n)+/g, '<br>'));
        $confirm.popbox({zIndex:1060});
        var $confirmok = $confirm.find("#confirm-ok");
        $confirmok.focus().unbind().click(function(){
            $confirm.popbox('hide');
            if($$.isFunction(callback)) callback();
            window.confirmOK = null;
        });
    }
    
    //fake prompt
    var $prompt = $$('<div>').addClass("popbox fade").hide();
    $prompt.html('<div class="popbox-header">'
                + '<button aria-hidden="true" data-dismiss="popbox" class="close" type="button">×</button>'
                + '<h3 id="prompt-title"></h3>'
                + '</div>'
                + '<div class="popbox-body dm-setting-form" id="prompt-body"></div>'
                + '<div class="popbox-footer">'
                + '<a data-dismiss="popbox" href="javascript:">取消</a>'
                + '<input class="btn btn-success btn-big" type="submit" value="确 定" id="prompt-ok" /></div>').appendTo($body);
    $$.prompt = function(json){
        $prompt.find("#prompt-title").html(json.title || '');
        var html = template('<dl class="dm-form-textinput-line clearfix">'
                            + '<dt>{name}</dt>'
                            + '<dd><input class="dm-input-text" type="{type|text}" value="{value|}" placeholder="{hint}"><span class="dm-error"></span></dd></dl>', json.fields);
        var $promptBody = $prompt.find("#prompt-body");
        $promptBody.html(html);
        $prompt.popbox();
        
        var $inputs = $promptBody.find("input.dm-input-text");
        $inputs[0].focus();
        var $promptok = $prompt.find("#prompt-ok");
        $promptok.unbind().bind("click", function(){
            var vals = [];
            $inputs.each(function(){
                vals.push(this.value); 
            });
            if($$.isFunction(json.check)){
                var result = json.check(vals);
                if(!result.pass){
                    $$.map(result.msg, function(txt, i){
                        $inputs.eq(i).parent().find(".dm-error").html(txt);
                    });
                    $inputs[0].focus();
                    return;
                }
            }
            if($$.isFunction(json.callback)){
                json.callback(vals);
            }
            $prompt.popbox('hide');
        });
        json.init && json.init($prompt);
    }
    
    function template(temp, data, regexp){
        var isarr = $$.isArray(data);
	    if(!isarr) data = [data];
	    var ret = [];
	    for(var i=0,j=data.length; i < j; i++){
		    ret.push(replaceAction(data[i]));
	    }
	    return ret.join("");
	    function replaceAction(object){
		    return temp.replace(regexp || (/\\?\{([^}]+)\}/g), function(match, name){
			    if (match.charAt(0) == '\\') return match.slice(1);
                var _val = '';
                if(/(\S+)\|(\S*)/.test(name)){
                    name = RegExp.$1;
                    _val = RegExp.$2;
                }
			    return (object[name] != undefined) ? object[name] : _val;
		    });
	    }
    }
    
    //fake alert
    var $alert = $$('<div>').addClass("popbox fade").hide();
    $alert.html('<div class="popbox-header">'
                + '<button aria-hidden="true" data-dismiss="popbox" class="close" type="button">×</button>'
                + '<h3>提示</h3>'
                + '</div>'
                + '<div class="popbox-body alert-body" id="alert-body"></div>'
                + '<div class="popbox-footer">'
                + '<input class="btn btn-success btn-big" type="submit" value="确 定" data-dismiss="popbox" /></div>').appendTo($body);
    $$.alert = function(msg){
        var $alertBody = $alert.find("#alert-body");
        if($alert.isPoped()){
            var tmp = $alertBody.html() + '<br>';
            $alertBody.html(tmp + msg.replace(/(\r|\n)+/g, '<br>'));
            $alert.popbox("repos");
        }else{
            $alertBody.html(msg.replace(/(\r|\n)+/g, '<br>'));
            $alert.popbox({zIndex:1060}); //默认backdrop/pop zIndex=1040/1050
            $alert.find(".btn-success").focus();
        }
    }
    
})();
